package swing;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import modele.Formation;
import dao.FormationDAO;

public class FormationListePanel extends JPanel {

	private static final long			serialVersionUID	= 1L;
	// private JTextField textRecherche;
	private JList<Formation>			listeFormation;
	private ArrayList<Formation>		formations;
	private DefaultListModel<Formation>	listeFormationModel;
	private FormationPanel				formationPanel;
	private JCheckBox					rechercheParTheme;
	protected int						selectedListItem;
	private JTextField					textRecherche;
	private JButton						btnSupprimer;
	private JButton						btnNouvelleFormation;
	private JScrollPane					formationScrollPane;

	public FormationListePanel() {
		setBorder(new EmptyBorder(10, 10, 10, 10));
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 0, 0, 0, 0 };
		gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0, 0 };
		gridBagLayout.columnWeights = new double[] { 1.0, 0.0, 0.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 1.0, 0.0, Double.MIN_VALUE };
		setLayout(gridBagLayout);

		JLabel lblRechercheParCode = new JLabel("Recherche par code, titre, pre-requis, certification et themes");
		GridBagConstraints gbc_lblRechercheParCode = new GridBagConstraints();
		gbc_lblRechercheParCode.insets = new Insets(0, 0, 5, 5);
		gbc_lblRechercheParCode.gridx = 0;
		gbc_lblRechercheParCode.gridy = 0;
		add(lblRechercheParCode, gbc_lblRechercheParCode);

		textRecherche = new JTextField();
		textRecherche.setHorizontalAlignment(JTextField.LEFT);
		textRecherche.setBorder(new EmptyBorder(10, 10, 10, 10));
		GridBagConstraints gbc_textRecherche1 = new GridBagConstraints();
		gbc_textRecherche1.insets = new Insets(0, 0, 5, 5);
		gbc_textRecherche1.fill = GridBagConstraints.HORIZONTAL;
		gbc_textRecherche1.gridx = 0;
		gbc_textRecherche1.gridy = 1;
		add(textRecherche, gbc_textRecherche1);
		textRecherche.setColumns(10);

		rechercheParTheme = new JCheckBox("Inclure themes dans le resultat");
		rechercheParTheme.setSelected(false);
		GridBagConstraints gbc_chckbxInclureThemes = new GridBagConstraints();
		gbc_chckbxInclureThemes.anchor = GridBagConstraints.EAST;
		gbc_chckbxInclureThemes.insets = new Insets(0, 0, 5, 5);
		gbc_chckbxInclureThemes.gridx = 0;
		gbc_chckbxInclureThemes.gridy = 2;
		add(rechercheParTheme, gbc_chckbxInclureThemes);

		formationScrollPane = new JScrollPane();
		GridBagConstraints gbc_scrollPane = new GridBagConstraints();
		gbc_scrollPane.insets = new Insets(0, 0, 5, 5);
		gbc_scrollPane.fill = GridBagConstraints.BOTH;
		gbc_scrollPane.gridx = 0;
		gbc_scrollPane.gridy = 3;
		add(formationScrollPane, gbc_scrollPane);

		JPanel panel = new JPanel();
		GridBagConstraints gbc_panel = new GridBagConstraints();
		gbc_panel.insets = new Insets(0, 0, 0, 5);
		gbc_panel.fill = GridBagConstraints.BOTH;
		gbc_panel.gridx = 0;
		gbc_panel.gridy = 4;
		add(panel, gbc_panel);

		btnSupprimer = new JButton("Supprimer");
		panel.add(btnSupprimer);

		btnNouvelleFormation = new JButton("Nouvelle formation");
		panel.add(btnNouvelleFormation);

		addRecherche();
		addFormationListe();

		setBtnActions();

	}

	/**
	 * Remplir JList listeFormation avec toutes les formations proposees.
	 * Pour chaque element choisi dans la liste, on definit
	 * ListeSelectionListener
	 */
	public void addFormationListe() {

		listeFormationModel = new DefaultListModel<Formation>();

		formations = new ArrayList<Formation>();

		try {
			formations = (ArrayList<Formation>) FormationDAO.listerFormation();

			for (Formation formation : formations) {
				listeFormationModel.addElement(formation);
			}

		} catch (SQLException e) {
			e.printStackTrace();
		}

		listeFormation = new JList<Formation>(listeFormationModel);

		// listeFormation.setFixedCellHeight(60);

		ListSelectionListener listSelectionListener = new ListSelectionListener() {

			@SuppressWarnings("unchecked")
			public void valueChanged(ListSelectionEvent listSelectionEvent) {

				boolean adjust = listSelectionEvent.getValueIsAdjusting();

				if (!adjust) {

					@SuppressWarnings("rawtypes")
					JList<String> list = (JList) listSelectionEvent.getSource();

					final int choisi = list.getSelectedIndex();

					// System.out.println("choisi : index " + choisi);
					// System.out.println(formations.get(choisi));
					if (choisi > -1) {
						selectedListItem = choisi;
						formationPanel.lireFormation(formations.get(choisi).getIdFormation());
					}

				}

			}
		};
		listeFormation.addListSelectionListener(listSelectionListener);
		listeFormation.setCellRenderer(new FormationListCellRenderer());
		listeFormation.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		formationScrollPane.setColumnHeaderView(setFormationListLabels());
		formationScrollPane.setViewportView(listeFormation);

	}

	/**
	 * Definition des actions lies aux butons.
	 * Un button supprime la formation apres la confirmation de l'utilisateur
	 */
	public void setBtnActions() {
		btnNouvelleFormation.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				newFormation();

			}
		});

		btnSupprimer.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				Formation formation = null;
				if (listeFormationModel.size() > 0) {
					formation = listeFormationModel.get(selectedListItem);
				}
				// Formation formation = listeFormation.getSelectedValue();

				if (formation == null) {
					System.out.println("f null");
					return;
				}

				final int formationId = formation.getIdFormation();
				System.out.println("supprimer" + formationId);

				int result = JOptionPane.showConfirmDialog(FormationListePanel.this, "Voulez-vous supprimer la formation selectionne ?",
						"Supprimer la formation", JOptionPane.YES_NO_OPTION);
				switch (result) {
					case JOptionPane.YES_OPTION:
						delFormation(formationId);
						return;
					case JOptionPane.NO_OPTION:
						return;
					case JOptionPane.CLOSED_OPTION:
						return;

				}

			}
		});
	}

	/**
	 * Definition un KeyListener.
	 * Quand l'utilisateur recherche une formation, ce champs de saisie remplit
	 * la liste à la vole.
	 * Touche Escape supprime le mot de recherche
	 */
	public void addRecherche() {

		textRecherche.addKeyListener(new KeyListener() {

			@Override
			public void keyTyped(KeyEvent e) {
			}

			@Override
			public void keyReleased(KeyEvent e) {
				int keyCode = e.getKeyCode();
				switch (keyCode) {
					case KeyEvent.VK_ESCAPE:
						textRecherche.setText("");
						listeFormationModel.clear();
						break;
					default:
						String requete = textRecherche.getText();
						rechercheFormation(requete);
						break;
				}
			}

			@Override
			public void keyPressed(KeyEvent e) {
			}
		});

		rechercheParTheme.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				//
				updateListe();
			}
		});

	}

	/**
	 * Pour bien distinguer la valeurs de champs dans la liste de formation,
	 * On ajoute des libelles ID, Code et Titre
	 * 
	 * @return JPanel
	 */
	public JPanel setFormationListLabels() {
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 0, 0, 0, 0 };
		gridBagLayout.rowHeights = new int[] { 0, 0 };
		gridBagLayout.columnWeights = new double[] { 0.0, 0.0, 1.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
		JPanel formationListFullLabels = new JPanel();
		formationListFullLabels.setLayout(gridBagLayout);

		JLabel labelId = new JLabel("ID");
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 0, 5);
		gbc_lblNewLabel.gridx = 0;
		gbc_lblNewLabel.gridy = 0;
		labelId.setBorder(new EmptyBorder(10, 10, 10, 10));
		formationListFullLabels.add(labelId, gbc_lblNewLabel);

		JLabel labelCode = new JLabel("CODE");
		GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
		gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel_1.insets = new Insets(0, 0, 0, 5);
		gbc_lblNewLabel_1.gridx = 1;
		gbc_lblNewLabel_1.gridy = 0;
		labelCode.setBorder(new EmptyBorder(10, 10, 10, 10));
		formationListFullLabels.add(labelCode, gbc_lblNewLabel_1);

		JLabel labelTitre = new JLabel("TITRE");
		GridBagConstraints gbc_lblGestionDeProjet = new GridBagConstraints();
		gbc_lblGestionDeProjet.anchor = GridBagConstraints.WEST;
		gbc_lblGestionDeProjet.gridx = 2;
		gbc_lblGestionDeProjet.gridy = 0;
		labelTitre.setBorder(new EmptyBorder(10, 10, 10, 10));
		formationListFullLabels.add(labelTitre, gbc_lblGestionDeProjet);
		return formationListFullLabels;
	}

	public void setFormationPanel(FormationPanel formationPanel) {
		this.formationPanel = formationPanel;
	}

	/**
	 * Recherche les formations à partir du mot saisie.
	 * Si la requete est null, il retourne toutes les formations
	 * Si recherche par theme est active, il retourne les formations par rapport
	 * aux themes
	 * 
	 * @param requete
	 */
	public void rechercheFormation(String requete) {

		boolean listAll = false;

		if (!requete.isEmpty() && !requete.matches("^\\s*$")) {
			listAll = false;
		} else {
			System.out.println("requete is empty");
			listAll = true;
		}

		System.out.println("Requete => " + requete);

		formations = new ArrayList<Formation>();

		try {

			if (listAll) {
				formations = (ArrayList<Formation>) FormationDAO.listerFormation();
			} else {
				formations = (ArrayList<Formation>) FormationDAO.rechercheMultiWithTheme(requete, rechercheParTheme());
			}

			listeFormationModel.clear();

			for (Formation formation : formations) {
				listeFormationModel.addElement(formation);
			}

			listeFormation = new JList<Formation>(listeFormationModel);
			// listeFormation.notify();

		} catch (SQLException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * Si la recherche par theme active
	 * 
	 * @return
	 */
	public boolean rechercheParTheme() {
		return rechercheParTheme.isSelected();
	}

	public void updateListe() {
		listeFormation.clearSelection();
		rechercheFormation("");
	}

	/**
	 * Initialise à par defaut les champs de saisie afin de creer une nouvelle
	 * formation
	 */
	public void newFormation() {
		//
		System.out.println("new formation");
		listeFormation.clearSelection();
		formationPanel.updateTextField(new Formation());
		formationPanel.focus();

	}

	/**
	 * Supprime definitivement la formation selectionne
	 * 
	 * @param idFormation
	 */
	public void delFormation(int idFormation) {
		//

		System.out.println("del formation" + idFormation);

		try {
			FormationDAO.supprimer(idFormation);
			System.out.println("La formation dont l'ID est " + idFormation + " a été éffacée.");
			formationPanel.updateTextField(new Formation());

			int selectedIndex = listeFormation.getSelectedIndex();
			if (selectedIndex != -1) {
				listeFormationModel.remove(selectedIndex);
			}
			updateListe();

		} catch (SQLException e) {
			JOptionPane.showMessageDialog(this, "La formation n'a pu être supprimee \n Erreur code :" + e.getErrorCode(), "Supprimer la formation",
					JOptionPane.INFORMATION_MESSAGE);
			e.printStackTrace();
		}

	}

}
